#ifndef __V4L2_H__
#define __V4L2_H__


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <string.h>
#include <sys/mman.h>

typedef int CamId;
typedef unsigned int uint;
typedef unsigned char uchar;

typedef struct userbuffer {
    uchar* start;
    uint length;
} userbuffer;

typedef struct {
    unsigned char * start = NULL;
    unsigned int width;
    unsigned int height;
    unsigned int length;
} ImgBuf;

enum Status {
    SUCCESS = 0,
    ERROR_CLOSE_CAPTURE     = 1,
    ERROR_VIDIOC_ENUM_FMT   = 2,
    ERROR_VIDIOC_S_FMT      = 3,
    ERROR_VIDIOC_G_FMT      = 4,
    ERROR_VIDIOC_REQBUFS    = 5,
    ERROR_VIDIOC_QUERYBUF   = 6,
    ERROR_VIDIOC_QBUF       = 7,
    ERROR_VIDIOC_STREAMON   = 8,
    ERROR_VIDIOC_STREAMOFF  = 9,
    ERROR_VIDIOC_DQBUF      = 10
};

// 1.打开UVC设备
CamId v4l2_init(const char* device);

// 2.获取UVC支持格式
Status v4l2_get_support_formats(CamId fd);

// 3.配置UVC采集格式
Status v4l2_set_capture_format(CamId fd, uint width, uint height);

// 4.申请内核缓冲区队列
Status v4l2_request_core_buffer(CamId fd);

// 5.把内核缓冲区队列映射到用户空间
Status v4l2_map_buffer(CamId fd, ImgBuf* &buffer);

// 6.开始采集
Status v4l2_start_stream(CamId fd);

// 7.采集数据 - 上锁
Status v4l2_get_frame(CamId fd, v4l2_buffer &readbuffer);

// 8.采集数据 - 解锁
Status v4l2_release_frame(CamId fd, v4l2_buffer &readbuffer);

// 9.停止采集
Status v4l2_stop_stream(CamId fd);

// 10.释放映射
Status v4l2_munmap_buffer(ImgBuf* &buffer);

// 11.关闭设备
Status v4l2_close(CamId fd);

#endif  // __V4L2_H__